package tss;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

public class TransportImpl extends Layer implements Transport {
	private Layer[] layers;
	private Queue<Message> upQueue = new LinkedList<Message>();
	
	/**
	 * Create a TransportImpl containing the provided layers 
	 * with this TransportImpl as top layer followed by layers[0],
	 * ..., layers[layers.length - 1]
	 *  
	 * @param layers
	 */
	public TransportImpl(Layer ... layers) {
		this.layers = new Layer[layers.length + 1];
		this.layers[0] = this;
		for (int i = 0; i < layers.length; i++) {
			this.layers[i + 1] = layers[i];
			this.layers[i].setLowerLayer(this.layers[i + 1]);
			this.layers[i + 1].setUpperLayer(this.layers[i]);
		}
	}
	
	public void setProperties(String ... properties) {
		super.setProperties(properties);
		for (int i = 1; i < layers.length; i++) {
			layers[i].setProperties(properties);
		}
	}
	
	public void send(Message message) throws IOException {
		down(message);
	}
	
	public synchronized Message peek() {
		return upQueue.peek();
	}
	
	public synchronized Message receive() {
		try {
			if (upQueue.isEmpty()) {
				wait();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return upQueue.poll();
	}
	
	public synchronized void up(Message message) {
		upQueue.offer(message);
		notifyAll();
	}
}
